parameters:
  buildConfig: ''
  osGroup: ''
  archType: ''
  osSubgroup: ''
  platform: ''
  crossBuild: false
  timeoutInMinutes: 120
  condition: true
  shouldContinueOnError: false
  container: ''
  buildSteps: []
  dependsOn: []
  globalBuildSuffix: ''
  variables: []
  name: ''
  displayName: ''
  runtimeVariant: ''
  pool: ''

  # The target names here should match container names in the resources section in our pipelines, like runtime.yml
  packageDistroList:
  - target: debpkg
    packageType: deb
    packagingArgs: /p:BuildDebPackage=true
  - target: rpmpkg
    packageType: rpm
    packagingArgs: /p:BuildRpmPackage=true

  isOfficialBuild: false
  buildFullPlatformManifest: false

  liveRuntimeBuildConfig: ''
  liveLibrariesBuildConfig: ''
  runtimeFlavor: 'coreclr'
  unifiedArtifactsName: ''
  unifiedBuildNameSuffix: ''
  unifiedBuildConfigOverride: ''

### Product build
jobs:
- template: /eng/common/templates/job/job.yml
  parameters:
    buildConfig: ${{ parameters.buildConfig }}
    archType: ${{ parameters.archType }}
    osGroup: ${{ parameters.osGroup }}
    osSubgroup: ${{ parameters.osSubgroup }}
    runtimeVariant: ${{ parameters.runtimeVariant }}
    testGroup: ${{ parameters.testGroup }}
    helixType: 'build/product/'
    enableMicrobuild: true
    pool: ${{ parameters.pool }}

    # Compute job name from template parameters
    name: ${{ format('installer_{0}_{1}', coalesce(parameters.name, parameters.platform), parameters.buildConfig) }}
    displayName: ${{ format('Installer Build and Test {0} {1}', coalesce(parameters.name, parameters.platform), parameters.buildConfig) }}

    # Run all steps in the container.
    # Note that the containers are defined in platform-matrix.yml
    container: ${{ parameters.container }}

    timeoutInMinutes: ${{ parameters.timeoutInMinutes }}

    crossBuild: ${{ parameters.crossBuild }}

    gatherAssetManifests: true

    # Component governance does not work on musl machines
    ${{ if eq(parameters.osSubGroup, '_musl') }}:
      disableComponentGovernance: true

    variables:
    - ${{ each variable in parameters.variables }}:
      - ${{ variable }}

    - name: BuildAction
      value: -test

    - name: buildCommandSourcesDirectory
      value: '$(Build.SourcesDirectory)/'

    - name: librariesBuildConfigArg
      value: -lc ${{ coalesce(parameters.liveLibrariesBuildConfig, parameters.buildConfig) }}

    - name: runtimeBuildConfigArg
      value: -rc ${{ coalesce(parameters.liveRuntimeBuildConfig, parameters.buildConfig) }}

    ###
    ### Platform-specific variable setup
    ###

    - ${{ if eq(parameters.osGroup, 'windows') }}:

      - name: CommonMSBuildArgs
        value: >-
          /p:TargetArchitecture=${{ parameters.archType }}
          /p:PortableBuild=true
          /p:RuntimeFlavor=${{ parameters.runtimeFlavor }}
      - name: TargetArchitecture
        value: ${{ parameters.archType }}

      - name: BaseJobBuildCommand
        value: >-
          build.cmd -subset host+packs -ci
          $(BuildAction)
          -configuration $(_BuildConfig)
          $(librariesBuildConfigArg)
          $(runtimeBuildConfigArg)
          $(CommonMSBuildArgs)

    - ${{ elseif eq(parameters.osGroup, 'osx') }}:

      - name: CommonMSBuildArgs
        value: >-
          /p:PortableBuild=true
          /p:RuntimeFlavor=${{ parameters.runtimeFlavor }}
          /p:TargetArchitecture=${{ parameters.archType }}
          /p:CrossBuild=${{ parameters.crossBuild }}

      - name: BaseJobBuildCommand
        value: >-
          $(Build.SourcesDirectory)/build.sh -subset host+packs -ci
          $(BuildAction)
          -configuration $(_BuildConfig)
          -arch ${{ parameters.archType }}
          $(librariesBuildConfigArg)
          $(runtimeBuildConfigArg)
          $(CommonMSBuildArgs)

    - ${{ elseif in(parameters.osGroup, 'linux', 'freebsd') }}:
      - name: CommonMSBuildArgs
        value: >-
          /p:Configuration=$(_BuildConfig)
          /p:TargetOS=${{ parameters.osGroup }}
          /p:TargetArchitecture=${{ parameters.archType }}
          /p:RuntimeFlavor=${{ parameters.runtimeFlavor }}

      - name: _PortableBuild
        value: ${{ eq(parameters.osSubgroup, '') }}

      - ${{ if and(eq(parameters.osSubgroup, '_musl'), eq(parameters.osGroup, 'linux')) }}:
        - name: _PortableBuild
          value: true

      - ${{ if eq(parameters.crossBuild, true) }}:
        - name: ArchArg
          value: -arch ${{ parameters.archType }}

      - name: BaseJobBuildCommand
        value: >-
          $(Build.SourcesDirectory)/build.sh -subset host+packs -ci
          $(BuildAction)
          $(librariesBuildConfigArg)
          $(runtimeBuildConfigArg)
          $(ArchArg)
          /p:CrossBuild=${{ parameters.crossBuild }}
          /p:PortableBuild=$(_PortableBuild)
          $(CommonMSBuildArgs)

      - name: installersSubsetArg
        value: --subset packs.installers

    dependsOn:
    - 'build_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ coalesce(parameters.unifiedBuildConfigOverride, parameters.buildConfig) }}_${{ parameters.unifiedBuildNameSuffix }}'
    - ${{ parameters.dependsOn }}
    steps:
      - ${{ if eq(parameters.osGroup, 'windows') }}:
        - template: /eng/pipelines/common/templates/disable-vsupdate-or-failfast.yml
      - checkout: self
        clean: true
        fetchDepth: $(checkoutFetchDepth)

      - ${{ if ne(variables['System.TeamProject'], 'public') }}:
        - ${{ if ne(parameters.osGroup, 'windows') }}:
          - task: Bash@3
            displayName: Setup Private Feeds Credentials
            inputs:
              filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
              arguments: $(Build.SourcesDirectory)/NuGet.config $Token
            env:
              Token: $(dn-bot-dnceng-artifact-feeds-rw)
        - ${{ else }}:
          - task: PowerShell@2
            displayName: Setup Private Feeds Credentials
            inputs:
              filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
              arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
            env:
              Token: $(dn-bot-dnceng-artifact-feeds-rw)

      - template: /eng/pipelines/common/download-artifact-step.yml
        parameters:
          unpackFolder: $(Build.SourcesDirectory)/artifacts/bin
          artifactFileName: '${{ parameters.unifiedArtifactsName }}$(archiveExtension)'
          artifactName: '${{ parameters.unifiedArtifactsName }}'
          displayName: 'unified artifacts'

      - ${{ if in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator') }}:
        - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }}
          displayName: Install Build Dependencies

        - script: |
            du -sh $(Build.SourcesDirectory)/*
            df -h
          displayName: Disk Usage before Build

      - script: $(BaseJobBuildCommand)
        displayName: Build
        continueOnError: ${{ eq(parameters.shouldContinueOnError, true) }}

      - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}:
        - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log
          displayName: Collect vslogs on exit
          condition: always()

      - ${{ if in(parameters.osGroup, 'osx', 'ios', 'tvos') }}:
        - script: |
            du -sh $(Build.SourcesDirectory)/*
            df -h
          displayName: Disk Usage after Build

      # Only in glibc leg, we produce RPMs and Debs
      - ${{ if and(eq(parameters.runtimeFlavor, 'coreclr'), or(eq(parameters.platform, 'linux_x64'), eq(parameters.platform, 'linux_arm64')), eq(parameters.osSubgroup, ''))}}:
        - ${{ each packageBuild in parameters.packageDistroList }}:
          # This leg's RID matches the build image. Build its distro-dependent packages, as well as
          # the distro-independent installers. (There's no particular reason to build the distro-
          # independent installers on this leg, but we need to do it somewhere.)
          # Currently, linux_arm64 supports 'rpm' type only.
          - ${{ if or(not(eq(parameters.platform, 'linux_arm64')), eq(packageBuild.packageType, 'rpm')) }}:
            - template: /eng/pipelines/installer/jobs/steps/build-linux-package.yml
              parameters:
                packageType: ${{ packageBuild.packageType }}
                target: ${{ packageBuild.target }}
                packageStepDescription: Runtime Deps, Runtime, Framework Packs installers
                subsetArg: $(installersSubsetArg)
                packagingArgs: ${{ packageBuild.packagingArgs }}

      - template: /eng/pipelines/installer/jobs/steps/upload-job-artifacts.yml
        parameters:
          name: ${{ coalesce(parameters.name, parameters.platform) }}
          runtimeFlavor: ${{ parameters.runtimeFlavor }}
          runtimeVariant: ${{ parameters.runtimeVariant }}

      - ${{ if ne(parameters.osGroup, 'windows') }}:
        - script: set -x && df -h
          displayName: Check remaining storage space
          condition: always()
          continueOnError: true
